#ifndef DX_TYPE_H
#define DX_TYPE_H

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief 类型定义
*/
#include "sys_inc.h"

enum DXType {
    TYPE_UNKNOWN = -1,
    TYPE_BIT1,
//    TYPE_BIT2,
    TYPE_INT8,
    TYPE_INT16,
//    TYPE_INT24,
    TYPE_INT32,
    TYPE_UINT8,
    TYPE_UINT16,
//    TYPE_UINT24,
    TYPE_UINT32,
    TYPE_FLOAT,
    TYPE_FLOAT_abcd,
    TYPE_FLOAT_dcba,
    TYPE_FLOAT_badc,
    TYPE_FLOAT_cdab,
    TYPE_BYTES,
//    TYPE_TIME,
    TYPE_INT32_L,
    TYPE_UINT32_L,

    TYPE_INT64,
    TYPE_UINT64,
    TYPE_INT64_L,
    TYPE_UINT64_L,

    TYPE_STR,
    TYPE_STRING,

    MAX_TYPE
};

static const char *TypeString [] = {
    "bit1", /*"bit2",*/
    "s8", "s16", /*"s24",*/ "s32",
    "u8", "u16", /*"u24",*/ "u32",
    "float", "float_abcd", "float_dcba", "float_badc", "float_cdab",
    "bytes",
    "s32_l", "u32_l",
    "s64",   "u64",
    "s64_l", "u64_l",
    "str", "string"
};

static inline const char* DxTypeToString(DXType type)
{
    if (type < MAX_TYPE && type != TYPE_UNKNOWN)
        return TypeString[type];
    else
        return "unknown";
}
static inline DXType StringToDxType(const char *str)
{
    std::string txt = str;
    std::transform(txt.begin(), txt.end(), txt.begin(), ::tolower);
    for (int i=0; i<(sizeof(TypeString)/sizeof(TypeString[0])); i++) {
        if (strcmp(txt.c_str(), TypeString[i]) == 0)
        {
            return static_cast<DXType>(i);
        }

    }
    return TYPE_UNKNOWN;
}
static inline uint8_t DxTypeSize(DXType type)
{
    uint8_t len = 1;
    switch (type) {
    case TYPE_INT8:
    case TYPE_UINT8:
        len=1;
        break;
    case TYPE_INT16:
    case TYPE_UINT16:
        len=2;
        break;
    case TYPE_INT32:
    case TYPE_UINT32:
    case TYPE_INT32_L:
    case TYPE_UINT32_L:
    case TYPE_FLOAT:
    case TYPE_FLOAT_abcd:
    case TYPE_FLOAT_dcba:
    case TYPE_FLOAT_badc:
    case TYPE_FLOAT_cdab:
        len=4;
        break;
    case TYPE_INT64:
    case TYPE_UINT64:
    case TYPE_INT64_L:
    case TYPE_UINT64_L:
        len=8;
        break;
    default:
        break;
    }
    return len;
}

typedef struct TagDateTime {
    uint16_t ms;
    uint8_t  sec;
    uint8_t  min;
    uint8_t  hour;
    uint8_t  day;
    uint8_t  mon;
    uint16_t year;
}DateTime_t;


enum DXErrCode {
    ERR_NO_ERROR = 0,
    ERR_LINK_NOT_OPEN,
    ERR_SEND_FAILED,
    ERR_RECV_TIMEOUT,
    ERR_CRC_CHECK_FAILED,
    ERR_RECV_DATA_ERROR,
    ERR_SLAVE_RET_ERR,
    ERR_SLAVE_FUNC_ERR
};

static inline bool DXRespondActived(int err)
{
    return (err == ERR_NO_ERROR || err == ERR_SLAVE_RET_ERR);
}

static inline const char * DXErrorString(int code)
{
    switch (code) {
    case ERR_NO_ERROR:
        return "success";
    case ERR_LINK_NOT_OPEN:
        return "not open";
    case ERR_SEND_FAILED:
        return "发送失败";
    case ERR_RECV_TIMEOUT:
        return "接收超时";
    case ERR_CRC_CHECK_FAILED:
        return "CRC校验错误";
    case ERR_RECV_DATA_ERROR:
        return "接收数据错误";
    case ERR_SLAVE_RET_ERR:
        return "传感器返回异常";
    default:
        return "unknown";
    }
}

#endif // DX_TYPE_H
